package com.android.volley.socket;


import com.android.volley.AuthFailureError;
import com.android.volley.BuildConfig;
import com.android.volley.Request;
import com.android.volley.codec.CodecFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class SocketStack {
    private static final int TIME_OUT = 15000;
    private static final int MAX_BUFFER_SIZE = 5242880;//5M

    private SocketAddressSwitcher mSwitcher;

    public SocketStack(SocketAddressSwitcher switcher){
        mSwitcher = switcher;
    }

    public byte[] performRequest(Request<?> request) throws IOException, AuthFailureError {
        byte[] send = request.getBody();
        Socket socket = initSocket();
        send(socket,send);
        byte[] received = receive(socket);
        closeSocket(socket);
        return received;
    }

    public Socket initSocket() throws IOException {
        final ServerAddress serverAddress = mSwitcher.getServerAddress();
        Socket socket = new Socket(serverAddress.ip, serverAddress.port);
        socket.setSoTimeout(TIME_OUT);
        return socket;
    }

    public static  Socket initSocket(ServerAddress address)throws IOException {
        Socket socket = new Socket(address.ip, address.port);
        socket.setSoTimeout(TIME_OUT);
        return socket;
    }

    public static void closeSocket(Socket socket) throws IOException {
        if (!socket.isClosed()) {
            socket.close();
        }
    }

    public static void send(Socket socket, byte[] bytes) throws IOException {
        if (BuildConfig.Secret) {
            if (socket.getPort()==11645){//11645端口，服务器将接收内容当字符串处理，需要进行base64编码
                bytes = CodecFactory.getEncoder(socket).encode(bytes,true);
            }else{//11647端口不需要。。。
                bytes = CodecFactory.getEncoder(socket).encode(bytes,false);
            }
        }

        OutputStream out = socket.getOutputStream();
        IOUtil.writeInt(out, bytes.length);
        out.write(bytes);
    }

    public static byte[] receive(Socket socket) throws IOException {
        InputStream in = socket.getInputStream();
        int totalLength = IOUtil.readInt(in);
        if (totalLength>0 && totalLength < MAX_BUFFER_SIZE){
            byte[] read = IOUtil.read(in, totalLength);
            if (BuildConfig.Secret) {
                if (socket.getPort()==11645){
                    return CodecFactory.getDecoder(socket).decode(read,true);
                }else{
                    return CodecFactory.getDecoder(socket).decode(read,false);
                }
            }else{
                return read;
            }
        }else {
            throw new IOException("数据长度："+totalLength);
        }
    }


}
